# -*- coding: utf-8 -*-
"""
# @created on : 9月 2021/9/15 15:31
# @author     : kevin
# @file       : run_main.py
# @software   : PyCharm
# @project    : auto_interface_test


@license: (C) Copyright 2019-2025, Corporation Limited.
@desc:
"""
from basic_method.api_request import RunMethod
from basic_method.get_excel_data import GetExcelData
from data_config.header import MyHeader
from common.logger import Logger
from basic_method.compare import Compare
from utils.operation_excel import OperationExcel
from data_config.multipart import Multipart, UpdataData
from basic_method.variable import OperationVariable


class RunTest:
    def __init__(self):
        self.run_method = RunMethod()
        self.data = GetExcelData()
        self.log = Logger()
        self.comp = Compare()
        self.op = OperationExcel(sheet_name='data')
        self.mul = Multipart()
        self.variable = OperationVariable()
        self.up_data = UpdataData()
        self.header = None
        self.my_head = MyHeader()

    def go_run(self):
        res = None
        test_counts = self.data.get_data_lines()
        print(f'共有{test_counts}条测试数据')
        for i in range(1, test_counts+1):
            if self.data.get_data_is_run(i) == 'Y':
                if self.data.get_case_run_by_data(i) == 'Y':
                    if self.data.get_suit_run_by_data(i) == 'Y':
                        # 获取接口URL
                        print(f'开始获取第{i}条数据')
                        url = self.data.get_url_by_data(i)
                        # 获取接口发送方式
                        method = self.data.get_method_by_data(i)
                        # 获取请求数据
                        data = self.data.get_data(i)
                        # 获取是否需要在访问后获取cookie
                        set_cookie = self.data.get_cookie_by_data(i)
                        # 获取是否需要在访问后获取token
                        set_token = self.data.get_token_by_data(i)
                        # 获取数据类型，有些特殊的数据类型是需要单独处理的
                        met = self.data.get_request_data_model(i)
                        # 获取后置数据提取参数
                        back = self.data.get_data_back_key(i)
                        # 获取提交数据需要的参数
                        need = self.data.get_need_data(i)
                        # 获取请求资源类型
                        req_type = self.data.get_req_type_by_data_id(i)
                        # 更新请求头
                        self.header = self.my_head.get_header(req_type)
                        # 获取预期结果设置
                        real_result = self.data.get_expect_data(i)
                        # 获取断言类型,目前规划断言先支持对相应头(header)响应体(response)或者返回数据（json）的支持
                        assert_type = self.data.get_assert_type_by_id(i)
                        # 如果有前置的参数，替换data里的值为变量参数的值
                        if need is not None:
                            data = self.up_data.up_data(need, data)
                        # 如果数据类型为multipart类型，先进行数据处理，再执行操作
                        if met == 'multipart':
                            simp = self.data.get_type_mark_by_data_id(i)
                            simp_len = self.data.get_type_len_by_data_id(i)
                            multipart_data = self.mul.to_form_data(data=data, simp_len=simp_len, headers=self.header, simp=simp)
                            print(f'第{i}行用例, meth is {method}, url is {url}, header is {self.header}')
                            res = self.run_method.method_main(method=method, url=url, data=multipart_data['data'], header=multipart_data['headers'])
                        else:
                            print(f'第{i}行用例, meth is {method}, url is {url} , header is {self.header}')
                            res = self.run_method.method_main(method=method, url=url, data=data, header=self.header)
                        # 如果有后置参数需要获取值，先处理后置参数列表，获取值并更新参数列表
                        if set_cookie == 'Y':
                            if res.status_code == 200:
                                for key, value in res.cookies.items():
                                    self.header = self.my_head.up_header({'Cookie': key + '=' + value})
                        if back is not None:
                            self.variable.update_variable(key=back, res=res)
                        if real_result is not None:
                            self.comp.check(row=i, response=res, check_point=real_result)
                    else:
                        self.log.logger('error', f'第{i}条数据对应的suit设置为不执行')
                else:
                    self.log.logger('error', f'第{i}条数据对应的case设置为不执行')
            else:
                self.log.logger('error', f'第{i}条数据设置为不执行')
        # return json.dumps(res, ensure_ascii=False, sort_keys=True, indent=4)

    def get_test_case(self):
        """
        获取测试用例，将测试用例封装成列表返回
        :return: 测试用例列表
        """
        run_list = []
        len_suit = self.data.get_suit_lines()
        # print(len_suit)
        for i in range(1, len_suit):
            if self.data.get_suit_is_run(i) == 'Y':
                case_list = self.data.get_dat_id_list_by_suit_id(i)
                for j in case_list:
                    # 获取接口发送方式
                    method = self.data.get_method_by_data(j)
                    # 获取URL
                    url = self.data.get_url_by_data(j)
                    # 获取数据是否运行
                    data_is_run = self.data.get_data_is_run(j)
                    # 获取case是否运行
                    case_is_run = self.data.get_case_run_by_data(j)
                    # 获取请求数据
                    data = self.data.get_data(j)
                    # 获取是否需要在访问后获取cookie
                    set_cookie = self.data.get_cookie_by_data(j)
                    # 获取是否需要在访问后获取token
                    set_token = self.data.get_token_by_data(j)
                    # 获取数据类型，有些特殊的数据类型是需要单独处理的
                    met = self.data.get_request_data_model(j)
                    # 获取后置数据提取参数
                    back = self.data.get_data_back_key(j)
                    # 获取变量需要的参数
                    need = self.data.get_need_data(j)
                    # 获取请求资源类型
                    req_type = self.data.get_req_type_by_data_id(j)
                    # 获取预期结果设置
                    real_result = self.data.get_expect_data(j)
                    # 获取断言类型,目前规划断言先支持对相应头(header)响应体(response)或者返回数据（json）的支持
                    assert_type = self.data.get_assert_type_by_id(j)
                    if case_is_run == 'Y':
                        if data_is_run == 'Y':
                            run_list.append({'suit_id': i,
                                             'case_id': j,
                                             'method': method,
                                             'url': url,
                                             'data': data,
                                             'data_type': met,
                                             'req_type': req_type,
                                             'back': back,
                                             'need': need,
                                             'set_cookie': set_cookie,
                                             'set_token': set_token,
                                             'check_point': real_result,
                                             'assert_type': assert_type})
                        else:
                            self.log.logger('info', f'第{j}条数据设置为不执行')
                    else:
                        self.log.logger('info', f'第{j}条数据对应的case设置为不执行')
            else:
                self.log.logger('info', f'第{i}条suit设置为不执行')
        return run_list